/*
 * Copyright (C) 2016 alchemystar, Inc. All Rights Reserved.
 */
package com.eblly.meta;

import java.sql.*;
import java.util.LinkedHashMap;
import java.util.Map;

import com.alibaba.druid.util.JdbcUtils;

import com.eblly.util.SqlUtil;
import com.jfinal.kit.JsonKit;
import lombok.Getter;
import lombok.Setter;

/**
 * 元数据
 *
 * @Author eblly
 */
@Getter
@Setter
public class MetaData {

    private Connection conn;
    private String user;
    private String password;
    private String schema;
    private String jdbcUrl;

    private String filterStr;

    private Map<String, Table> tableMap = new LinkedHashMap<>();

    public void init() {
        try {
            Class.forName(JdbcUtils.getDriverClassName(jdbcUrl));
            conn = DriverManager.getConnection(jdbcUrl, user, password);

            getInfoFromDb();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取数据库所有table
     *
     * @throws SQLException
     */
    private void getInfoFromDb() throws SQLException {
        ResultSet rs = SqlUtil.executeSql(conn, "show tables from " + schema);

        while (rs.next()) {
            Table table = new Table();

            String tableName = rs.getString("Tables_in_" + schema);
            table.setTableName(tableName);

            // 获取 createTable语句
            getCreateTableSql(table);

            // 获取table所有column
            getAllColumnsFromTable(table);

            // 获取table所有key
            getAllKeysFromTable(table);

            tableMap.put(table.getTableName(), table);
        }

//        System.out.println(JsonKit.toJson(tableMap));
    }

    /**
     * 获取create table 语句
     *
     * @throws SQLException
     */
    private void getCreateTableSql(Table table) throws SQLException {
        ResultSet rs = SqlUtil.executeSql(conn,
                                          "show create table " + schema + "." + table.getTableName());
        while (rs.next()) {
            table.setCreateTable(rs.getString("Create Table"));
        }
    }

    /**
     * 获取table所有 column
     * <p>
     *
     * @throws SQLException
     */
    private void getAllColumnsFromTable(Table table) throws SQLException {
        ResultSet rs = SqlUtil.executeSql(conn,
                                          "select  * from information_schema.columns where " + "TABLE_SCHEMA=" + "'"
                                                  + schema + "'" + " and " + "TABLE_NAME=" + "'"
                                                  + table.getTableName()
                                                  + "'" + " order by ORDINAL_POSITION asc");

        while (rs.next()) {
            Column column = new Column();

            column.setTableName(table.getTableName());
            column.setColumnName(rs.getString("COLUMN_NAME"));
            column.setColumnType(rs.getString("COLUMN_TYPE"));
            column.setColumnDefault(rs.getString("COLUMN_DEFAULT"));
            column.setIsNull(rs.getString("IS_NULLABLE"));
            column.setExtra(rs.getString("EXTRA"));
            column.setComment(rs.getString("COLUMN_COMMENT"));
            column.setOrdinalPosition(rs.getInt("ORDINAL_POSITION"));

            table.getColumnMap().put(column.getColumnName(), column);
        }
    }

    /**
     * 获取 table所有key
     * <p>
     *
     * @throws SQLException
     */
    private void getAllKeysFromTable(Table table) throws SQLException {
        ResultSet rs = SqlUtil.executeSql(conn,
                                          "show keys from " + schema + "." + table.getTableName());

        while (rs.next()) {
            String keyName = rs.getString("Key_name");
            String columnName = rs.getString("Column_name");

            if (!table.getKeyMap().containsKey(keyName)) {
                Key key = new Key();

                key.setIndexName(keyName);
                key.getColumnList().add(columnName);

                key.setNotUnique(rs.getString("Non_unique"));
                key.setIndexType(rs.getString("index_type"));
                key.setComment(rs.getString("comment"));
                key.setIndexComment(rs.getString("index_comment"));
                key.setSeqInIndex(rs.getInt("SEQ_IN_INDEX"));

                table.putKey(keyName, key);
            } else {
                table.addColumn2KeyMap(keyName, columnName);
            }
        }
    }


}
